package ru.ifmo.network.skype.network.data;

import javax.crypto.*;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

/**
 * @author avhaliullin
 */
public class Group implements Externalizable {
    private static final KeyGenerator KEY_GENERATOR;

    static {
        try {
            KEY_GENERATOR = KeyGenerator.getInstance("DES");
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        }
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(id);
        out.writeObject(name);
        out.writeObject(key);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        id = (Long) in.readObject();
        name = (String) in.readObject();
        key = (Key) in.readObject();
        initCiphers(key);
    }

    private long id;
    private String name;
    private Cipher cipher;
    private Cipher decipher;
    private Key key;

    public Group() {

    }

    public Group(long id, String name) {
        this.id = id;
        this.name = name;
        this.key = KEY_GENERATOR.generateKey();
        initCiphers(key);
    }

    private void initCiphers(Key key) {
        try {
            cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, key);

            decipher = Cipher.getInstance("DES");
            decipher.init(Cipher.DECRYPT_MODE, key);
        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new AssertionError(e);
        }
    }

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public boolean equals(Object o) {
        return (o instanceof Group) && ((Group) o).getId() == id && ((Group) o).getName().equals(name);
    }

    public byte[] decrypt(byte[] msg) throws IllegalBlockSizeException, BadPaddingException {
        return decipher.doFinal(msg);
    }

    public byte[] encrypt(byte[] msg) throws IllegalBlockSizeException, BadPaddingException {
        return cipher.doFinal(msg);
    }
}
